package com.svw.asmpcloud.util;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONArray;
import com.svw.asmpcloud.bean.UriSimpleGrantedAuthority;
import com.svw.asmpcloud.bean.User;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

public class TokenUtils implements Serializable {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(TokenUtils.class);
    private static final long serialVersionUID = -3L;
    /**
     * Token 有效时长
     */
    private static final Long EXPIRATION = 604800L;

    /**
     * 生成 Token 字符串 必须 setAudience 接收者 setExpiration 过期时间 role 用户角色
     * 
     * @param sysUser 用户信息
     * @return 生成的Token字符串 or null
     */
    public static String createToken(User sysUser) {
        // Token 的过期时间
        Date expirationDate = new Date(System.currentTimeMillis() + EXPIRATION * 1000);
        // 生成 Token
        List<UriSimpleGrantedAuthority> uris = sysUser.getUris();
        String json=JSONArray.toJSONString(uris);
        String token = Jwts.builder()
                // 设置 Token 签发者 可选
                .setIssuer("asmp")
                // 根据用户名设置 Token 的接受者
                .setAudience(sysUser.getUsername())
                // 设置过期时间
                .setExpiration(expirationDate)
                // 设置 Token 生成时间 可选
                .setIssuedAt(new Date())
                // 通过 claim 方法设置一个 key = role，value = userRole 的值
                 .claim("uri", json)
                // 设置加密密钥和加密算法，注意要用私钥加密且保证私钥不泄露
                .signWith(RsaUtils.getPrivateKey(), SignatureAlgorithm.RS256).compact();
        // return String.format("Bearer %s", token);
        return token;

    }
    
    /** 验证 Token ，并获取到用户名和用户权限信息
     * @param token Token 字符串
     * @return sysUser 用户信息
     */
    public static User validationToken(String token) {
        try {
            // 解密 Token，获取 Claims 主体
            Claims claims = Jwts.parserBuilder()
                    // 设置公钥解密，以为私钥是保密的，因此 Token 只能是自己生成的，如此来验证 Token
                    .setSigningKey(RsaUtils.getPublicKey())
                    .build().parseClaimsJws(token).getBody();
            if (claims == null) {
                return null;
            }
            // 验证 Token 有没有过期 过期时间
            Date expiration = claims.getExpiration();
            // 判断是否过期 过期时间要在当前日期之后
            if (!expiration.after(new Date())) {
                return null;
            }
            User sysUser = new User();
            sysUser.setUsername(claims.getAudience());
            Object object = claims.get("uri");
          //转化为数组
            List<UriSimpleGrantedAuthority> parseArray = JSONArray.parseArray((object.toString()),UriSimpleGrantedAuthority.class);
            sysUser.setUris(parseArray);
            return sysUser;
        } catch (Exception e) {
            LOGGER.error("error",e);
            return null;
        }
    }
}
